package com.ldu.exam.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.ldu.exam.dao.AccountRepository;
import com.ldu.exam.dao.SubmitPaperRepository;
import com.ldu.exam.model.AccountModel;
import com.ldu.exam.model.ClaModel;
import com.ldu.exam.model.SubmitPaper;

@Service
public class ScoreService 
{
	@Autowired SubmitPaperRepository repository;
	@Autowired AccountRepository accountRepository;
	
	
	public Page<SubmitPaper> findAllByUserId(String accountId, Pageable page)
	{
		Page<SubmitPaper> p = this.findBycondition(accountId, page);
		for (SubmitPaper s : p.getContent()) {
			if(!StringUtils.isEmpty(s.getAccountId()))
			{
				s.setAccountName(this.accountRepository.findById(s.getAccountId()).orElse(null).getNickname());
			}
		}
		return p;
	}
	
	private Page<SubmitPaper> findBycondition(String accountId,Pageable page)
	{
		return this.repository.findAll(new Specification<SubmitPaper>() {
			private static final long serialVersionUID = 1L;
			@Override
			public Predicate toPredicate(Root<SubmitPaper> root ,CriteriaQuery<?> query , CriteriaBuilder builder)
			{
				List<Predicate> list = new ArrayList<Predicate>();
				if(!StringUtils.isEmpty(accountId))
					list.add(builder.equal(root.<String>get("accountId"), accountId));
				Predicate[] pd = list.toArray(new Predicate[list.size()]);
				return builder.and(pd);
			}
		},page);
	}
	
	public Page<SubmitPaper> findForTeacher(String accountId,Pageable page)
	{
		AccountModel am = this.accountRepository.findById(accountId).orElse(null);
		List<AccountModel> list = new ArrayList<AccountModel>();
		if(am != null)
		{
			Set<ClaModel> set= am.getCla();
			for (ClaModel c : set) {
				for(AccountModel a : c.getStudentAccounts())
				{
					list.add(a);
				}
			}
		}
		Page<SubmitPaper> p = this.findBycondition1(list, page);
		for (SubmitPaper s : p.getContent()) {
			if(!StringUtils.isEmpty(s.getAccountId()))
			{
				s.setAccountName(this.accountRepository.findById(s.getAccountId()).orElse(null).getNickname());
			}
		}
		return p;
	}
	
	private Page<SubmitPaper> findBycondition1(List<AccountModel> accountIds,Pageable page)
	{
		return this.repository.findAll(new Specification<SubmitPaper>() {
			private static final long serialVersionUID = 1L;
			@Override
			public Predicate toPredicate(Root<SubmitPaper> root ,CriteriaQuery<?> query , CriteriaBuilder builder)
			{
//				List<Predicate> list = new ArrayList<Predicate>();
//				if(!StringUtils.isEmpty(accountId))
//					list.add(builder.in);
//				Predicate[] pd = list.toArray(new Predicate[list.size()]);
				Predicate predicate = root.isNotNull();
				CriteriaBuilder.In in = builder.in(root.<String>get("accountId"));
				for (AccountModel id : accountIds)
				{
					in.value(id.getId());
				}
				predicate = builder.and(predicate,in);
				return predicate;
			}
		},page);
	}
	
}
